<template>
	<!-- 标签栏 -->
	<my-tabs
		v-if="tabs.length"
		:current="currentTab"
		:tabs="tabs"
		@change="changeTab"
	/>
	
	<!-- 数据列表 -->
	<scroll-view
		class="data-list"
		scroll-y
		:style="{ height: listHeight }"
		:scroll-into-view="scrollIntoView"
		refresher-enabled
		:refresher-triggered="freshing"
		:refresher-background="refresherBackground"
		@refresherrefresh="pullToRefresh"
		@scrolltolower="bottomRefresh"
	>
		<view id="scrollTop"></view>
		<slot>
			<!-- 空内容组件 -->
			<my-empty v-if="status !== Status.loading && !pager.total"></my-empty>
		</slot>
		<!-- 加载提示组件 -->
		<u-loadmore v-if="!freshing && (status === Status.loading || pager.total)" class="loadmore" :status="status" />
	</scroll-view>
</template>

<script lang="ts" setup>
	import { ref, reactive, computed, onBeforeMount } from 'vue';
	import { throttle } from '@/utils';
	import { Tabs, Pager } from '@/types/interface';
	import { Status } from './data.d';
	
	const emits = defineEmits(['changeTab', 'initList', 'getList']);
	const props = defineProps({
		// 列表高度
		height: {
			type: String,
			default: '',
			require: false,
		},
		// 上拉背景色
		refresherBackground: {
			type: String,
			default: '#f4f5f8',
		},
		// 当前标签
		currentTab: {
			type: Number,
			default: 0,
		},
		// 标签栏
		tabs: {
			type: Array,
			default: () => [],
		},
	});
	
	// 设置竖向滚动条位置
	const scrollIntoView = ref('');
	// 下拉刷新状态
	const freshing = ref<boolean>(false);
	// 触底加载状态
	const status = ref<Status>(Status.loadmore);
	// 分页器
	const pager = reactive<Pager>({
		// 当前页码
		pageNum: 1,
		// 每页条数
		pageSize: 10,
		// 总条数
		total: 0,
	});
	
	// 列表高度
	const listHeight = computed(() => {
		// 如果组件有传入高度，以组件传入为主
		if (props.height) return props.height;
		// 状态栏高度
		const statusbarHeigth = 'var(--status-bar-height)';
		// 导航栏高度
		const navbarHeight = '44px';
		// 标签栏高度
		const tabsHeight = props.tabs.length ? '44px' : '0';
		// 返回列表高度
		return `calc(100vh - ${statusbarHeigth} - ${navbarHeight} - ${tabsHeight})`;
	});
	// 切换标签
	const changeTab = (tab: Tabs): void => {
		emits('changeTab', tab);
		initList();
	};
	
	// 执行回调
	const callback = (total: number) => {
		const { pageNum, pageSize } = pager;
		freshing.value = false;
		pager.total = total;
		scrollIntoView.value = '';
		status.value = (pageNum * pageSize >= total) ? Status.nomore : Status.loadmore;
	};
	// 初始化数据
	const initList = (): void => {
		if (status.value === 'loading') return;
		pager.pageNum = 1;
		emits('initList');
		getList();
		scrollIntoView.value = 'scrollTop';
	};
	// 获取数据
	const getList = throttle(() => {
		status.value = Status.loading;
		const { total, ...page } = pager;
		emits('getList', page, callback);
	}, 200);
	// 下拉刷新
	const pullToRefresh = (): void => {
		if (freshing.value) return;
		freshing.value = true;
		initList();
	};
	// 触底刷新
	const bottomRefresh = (): void => {
		if (status.value === 'loading') return;
		const { pageNum, pageSize, total } = pager;
		if (pageNum * pageSize >= total) return;
		pager.pageNum++;
		getList();
	};
	
	onBeforeMount(initList);
	defineExpose({
		initList,
	});
</script>

<style lang="scss" scoped>
	.data-list {
		::v-deep .uni-scroll-view-content {
			position: relative;
		}
		#scrollTop {
			position: absolute;
			top: -12rpx;
		}
		::v-deep .uni-scroll-view-refresher {
			margin: 12rpx 0 !important;
			.uni-scroll-view-refresh__spinner {
				circle {
					color: #3E9DBB !important;
				}
			}
			.uni-scroll-view-refresh__icon {
				fill: #3E9DBB !important;
			}
		}
		.loadmore {
			margin: 0 !important;
			padding: 12rpx 0 24rpx;
		}
	}
</style>
